/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package mbox.model;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import mbox.helper.Utilities;

/**
 *
 * @author Hallucinogen
 */
public class Metadata {
    private Metadata() {
        mFileChecksum = "";
    }

    public Metadata(Metadata other) {
        mFileChecksum   = "" + other.mFileChecksum;
        mFilePath       = "" + other.mFilePath;
        mFileType       = other.mFileType;
        mVersion        = other.mVersion;
    }

    public static Metadata createNewMetadata(String filePath) {
        Metadata retval = new Metadata();

        retval.mFilePath = filePath;
        retval.mVersion = 1;

        try {
            if (new File(filePath).isDirectory()) {
                retval.mFileChecksum    = Utilities.convertToSHA1(filePath);
                retval.mFileType        = Utilities.TYPE_FOLDER;
            } else {
                retval.mFileChecksum    = Utilities.convertToSHA1(Utilities.getFileByte(filePath));
                retval.mFileType        = Utilities.TYPE_FILE;
            }
        } catch (Exception ex) {
            System.out.println("Error while making metadata. Reason = " + ex);
        }

        return retval;
    }

    
    public static ArrayList<Metadata> readMetadatas(String metaPath) throws IOException {
        return readMetadatas(Utilities.getFileByte(metaPath));
    }

    public static ArrayList<Metadata> readMetadatas(byte[] data) {
        int fileCount = data[0];
        fileCount = (data[0] + 256) % 256;
        fileCount = (fileCount << 8) + (data[1] + 256) % 256;
        fileCount = (fileCount << 8) + (data[2] + 256) % 256;
        fileCount = (fileCount << 8) + (data[3] + 256) % 256;

        ArrayList<Metadata> retval = new ArrayList<Metadata>();

        int last = 4;

        for (int i = 0; i < fileCount; ++i) {
            Metadata metadata = new Metadata();

            int fileLength = data[last];
            ++last;

            StringBuilder sb = new StringBuilder();

            for (int j = 0; j < fileLength; ++j) {
                sb.append((char)data[last]);
                ++last;
            }
            metadata.mFilePath = sb.toString();

            metadata.mFileType = data[last];
            ++last;

            metadata.mVersion = (data[last] + 256) % 256; ++last;
            metadata.mVersion = ((metadata.mVersion << 8) + data[last] + 256) % 256; ++last;
            metadata.mVersion = ((metadata.mVersion << 8) + data[last] + 256) % 256; ++last;
            metadata.mVersion = ((metadata.mVersion << 8) + data[last] + 256) % 256; ++last;

            for (int j = 0; j < 40; ++j) {
                metadata.mFileChecksum += (char)data[last];
                ++last;
            }

            retval.add(metadata);
        }

        return retval;
    }

    public void writeMetadataToFile(BufferedOutputStream metaFileStream) {
        try {
            int length = mFilePath.length();

            // tulis file length
            metaFileStream.write((byte)length);

            // tulis file name
            for (int i = 0; i < length; ++i)
                metaFileStream.write(mFilePath.charAt(i));

            // tulis tipe file
            metaFileStream.write((byte)mFileType);

            // tulis nomer revisi
            metaFileStream.write((byte)((mVersion >> 24) % 256));
            metaFileStream.write((byte)((mVersion >> 16) % 256));
            metaFileStream.write((byte)((mVersion >> 8) % 256));
            metaFileStream.write((byte)(mVersion % 256));

            // tulis checksum
            for (int i = 0; i < 40; ++i)
                metaFileStream.write(mFileChecksum.charAt(i));
        } catch (IOException iEx) {
            
        }
    }

    public byte[] toSend() {
        StringBuilder sb = new StringBuilder();
        int length = mFilePath.length();

        sb.append((char)length);

        // tulis file name
        for (int i = 0; i < length; ++i)
            sb.append(mFilePath.charAt(i));

        // tulis tipe file
        sb.append((char)mFileType);

        // tulis nomer revisi
        sb.append((char)((mVersion >> 24) % 256));
        sb.append((char)((mVersion >> 16) % 256));
        sb.append((char)((mVersion >> 8) % 256));
        sb.append((char)(mVersion % 256));

        // tulis checksum
        for (int i = 0; i < 40; ++i)
            sb.append((char)mFileChecksum.charAt(i));


        String str = sb.toString();
        byte[] retval = new byte[str.length()];

        for (int i = 0; i < retval.length; ++i)
            retval[i] = (byte)str.charAt(i);

        return retval;
    }

    public String getFilePath() {
        return mFilePath;
    }

    public void setFilePath(String path) {
        mFilePath = path;
    }

    public void setVersion(int version) {
        mVersion = version;
    }

    public int getVersion() {
        return mVersion;
    }

    public String getChecksum() {
        return mFileChecksum;
    }

    public void setFileType(byte type) {
        mFileType = type;
    }

    public byte getFileType() {
        return mFileType;
    }

    private String mFilePath;
    private String mFileChecksum;
    private int mVersion;
    private byte mFileType;
}
